import Const from "./const"
import Vue from "vue"
import VueResource from "vue-resource"
import Core from "../core"
import router from 'src/router';
import { Message } from 'element-ui';

function Api() {
    Vue.use(VueResource);

    const apiList = {
        Dealer: {
            login: ['POST|dealer/login', 'username', 'password'],
			trackInsert: ['POST|dealer/track-insert', 'name', 'username', 'password'],
            trackAdd: ['POST|dealer/track-add', 'doctor_id'],
            trackRemove: ['POST|dealer/track-remove', 'id'],
            trackList: ['GET|dealer/track-list', 'page']
        },

        User: {
            list: ['GET|user/list', 'type', 'sp', 'page', 'limit'],
            info: ['GET|user/info', 'id']
        },

        Goods: {
            listAll: ['GET|goods/list-all', 'doctor_id'],
            goodsSharingSave: ['POST|goods/goods-sharing-save', 'doctor_id', 'goods_id', 'money']
        }
    };


    function generateApi() {
        let API = this;
        for (let moduleKey in apiList) {

            let moduleApiList = apiList[moduleKey];
            API[moduleKey] = {};

            for (let functionName in moduleApiList) {
                let config = moduleApiList[functionName];

                API[moduleKey][functionName] = ((config) => {
                    return (...args) => {
                        return post(config, ...args)
                    };
                })(config);
            }
        }
    }

    function getUrl(api, data) {
        let token = Core.Data.getToken() || "";
        let url = `${Const.NET.END_POINT}/${api}`;
        let params = {
            token: token
        };

        data = Object.assign(params, data);
        url = url + '?' + transformObjectToUrlencodedData(data);
        return url;
    }

	function makeToolRequest(api, body) {
		let token = Core.Data.getToken() || "";
		let url = `${Const.TOOL.END_POINT}/${api}`;
		let params = {
			token: token
		};

		body = Object.assign(params, body);
		url = url + '?' + transformObjectToUrlencodedData(body);

		console.log(url);

		let headers = {
			'Content-Type': 'application/x-www-form-urlencoded'
		};
		return new Promise((resolve, reject) => {
			Vue.http.post(url, transformObjectToUrlencodedData(body), { headers: headers }).then(
				response => {
					let body = response.body;
					if (response.data.hasOwnProperty('code') && response.data.code === Const.ERROR.ERROR_TOKEN_INVALID) {
						Core.Data.clearAuthData();
						router.push({ path: '/login' });
						return;
					}
					if (body.hasOwnProperty('code') && body.code === 0) {
						if (body.hasOwnProperty('error')) {
							console.error(body.error);
							handleError(body.error);
							return reject(body.error);
						} else {
							return resolve(body.data)
						}
					}

					handleError(body.message);
					return reject(body);
				},
				error => {
					handleError(error.message);
					reject(error);
				}
			);
		})
	}

	function doPost(url, data) {
        let headers = {
            'Content-Type': 'application/x-www-form-urlencoded'
        };
        console.log(url + "?" + transformObjectToUrlencodedData(data));

        return new Promise((resolve, reject) => {
            Vue.http.post(url, transformObjectToUrlencodedData(data), { headers: headers }).then(
                response => {
                    let body = response.body;
                    if (body.hasOwnProperty('code') && body.code === 0) {
                        if (body.hasOwnProperty('error')) {
                            console.error(body.error);
                            handleError(body.error);
                            return reject(body.error);
                        } else {
                            return resolve(body.data)
                        }
                    }

                    handleError(body.message);
                    return reject(body);
                },
                error => {
                    handleError(error.message);
                    reject(error);
                }
            );
        })
    }

    this.doPost = doPost;
    this.getUrl = getUrl;
    this.makeToolRequest = makeToolRequest;

    generateApi.call(this);

    function post(api, ...args) {
        let token = Core.Data.getToken() || "";
        let url = Core.Const.NET.END_POINT_ADMIN;

        let method = "GET";
        let apiArr = api[0].split("|");
        let routerPath = apiArr[0];
        if (apiArr.length === 2) {
            method = apiArr[0].toUpperCase();
            routerPath = apiArr[1];
        }

        url = `${url}/${routerPath}`;
        let body = '';

        let params = {
            token: token
        };

        let requestArr = {};
        for (let i = 1; i < api.length; i++) {
            let param = args[i - 1];
            param = param === undefined ? "" : param;
            // body += `&${api[i]}=${param}`
            requestArr[api[i]] = param;
        }

        body = Object.assign(params, requestArr);

        console.log(url + "?" + transformObjectToUrlencodedData(body));

        let headers = {
            'Content-Type': 'application/x-www-form-urlencoded'
        };
        return new Promise((resolve, reject) => {
            if (method == "GET") {
                Vue.http.get(`${url}?${transformObjectToUrlencodedData(body)}`).then(
                    response => {
                        let body = response.body;
                        if (response.data.hasOwnProperty('code') && response.data.code === Const.ERROR.ERROR_TOKEN_INVALID) {
                            Core.Data.clearAuthData();
                            router.push({ path: '/login' });
                            return;
                        }
                        if (body.hasOwnProperty('code') && body.code === 0) {
                            if (body.hasOwnProperty('error')) {
                                console.error(body.error);
                                handleError(body.error);
                                return reject(body.error);
                            } else {
                                return resolve(body.data)
                            }
                        }

                        handleError(body.message);
                        return reject(body);
                    },
                    error => {
                        handleError(error.message);
                        reject(error);
                    }
                )
            }
            if (method == "POST") {
                Vue.http.post(url, transformObjectToUrlencodedData(body), { headers: headers }).then(
                    response => {
                        let body = response.body;
                        if (response.data.hasOwnProperty('code') && response.data.code === Const.ERROR.ERROR_TOKEN_INVALID) {
                            Core.Data.clearAuthData();
                            router.push({ path: '/login' });
                            return;
                        }
                        if (body.hasOwnProperty('code') && body.code === 0) {
                            if (body.hasOwnProperty('error')) {
                                console.error(body.error);
                                handleError(body.error);
                                return reject(body.error);
                            } else {
                                return resolve(body.data)
                            }
                        }

                        handleError(body.message);
                        return reject(body);
                    },
                    error => {
                        handleError(error.message);
                        reject(error);
                    }
                );
            }

        })
    }

    function handleError(message) {
        Message({ type: "error", message: message });
    }

    function transformObjectToUrlencodedData(obj) {
        let p = [];
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                p.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
            }
        }
        return p.join('&');
    }

    return this;

}

export default new Api();
